package com.back.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;

import static com.github.yulichang.toolkit.MPJTableMapperHelper.getEntity;

@Slf4j
public class httpClient {
   private static PoolingHttpClientConnectionManager connectionManager;
    static {
        connectionManager = new PoolingHttpClientConnectionManager();
        connectionManager.setMaxTotal(200);         // 全局最大连接数
        connectionManager.setDefaultMaxPerRoute(20); // 每个路由最大连接数



    }
    public static String  doPostFile(String host, String path,
                                     Map<String, String> headers,
                                     Map<String, String> querys,
                                     MultipartFile file,
                                     Map<String, String> proxy)
            throws Exception {
        HttpPost request = new HttpPost(buildUrl(host, path, querys));
        // request.setConfig(requestConfig);
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }

        MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
        entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        entityBuilder.setCharset(Consts.UTF_8);
        entityBuilder.addBinaryBody("file", file.getInputStream(), ContentType.DEFAULT_BINARY, file.getOriginalFilename());
        request.setEntity(entityBuilder.build());
        return executeToPost(request, Consts.UTF_8.name(), proxy);
    }

    private static CloseableHttpClient getHttpsClient(RequestConfig config, Map<String, String> proxy) {
        CloseableHttpClient httpClient = null;
        if (proxy!=null && !proxy.isEmpty() && StringUtils.isNotBlank(proxy.get("proxyUsername")) && StringUtils.isNotBlank(proxy.get("proxyPassword"))
                && "1".equals(StringUtils.isNotBlank(proxy.get("openProxy")))) {

            CredentialsProvider provider = new BasicCredentialsProvider();
            provider.setCredentials(new AuthScope(config.getProxy()), new UsernamePasswordCredentials(proxy.get("proxyUsername"), proxy.get("proxyPassword")));
            httpClient = HttpClients.custom().setDefaultRequestConfig(config)
                    .setDefaultCredentialsProvider(provider)
                    // .setConnectionManager(connectionManager)
                    .build();
        } else {
            httpClient = HttpClients.custom().setDefaultRequestConfig(config)
                    // .setConnectionManager(connectionManager)
                    .build();
        }
        return httpClient;
    }


    private static RequestConfig getRequestConfig(Map<String, String> proxy) {
        RequestConfig config = null;
        //设置代理
        if (proxy!=null && !proxy.isEmpty() && "1".equals(proxy.get("openProxy"))) {
            int httpProxyPort = Integer.valueOf(proxy.get("proxyPort"));
            config = RequestConfig.custom()
                    .setProxy(new HttpHost(proxy.get("proxyHost"), httpProxyPort))
                    .setConnectTimeout(5000)// connectTimeout设置服务器请求超时时间
                    .setSocketTimeout(5000).build();// socketTimeout设置服务器响应超时时间
        } else {
            config = RequestConfig.custom()
                    .setConnectTimeout(5000)
                    .setSocketTimeout(5000).build();
        }
        return config;
    }


    private static String executeToPost(HttpPost httpPost, String responseEncoding,Map<String, String> proxy) throws IOException {
        //初始HttpClient
        RequestConfig requestConfig = getRequestConfig(proxy);
        CloseableHttpClient httpClient = getHttpsClient(requestConfig, proxy);

        try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
            response.getEntity();
            log.info("http status ---- {}", response.getStatusLine());
            String result = "null";
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                result = EntityUtils.toString(response.getEntity(), responseEncoding);
                log.info("返回结果:{}", result);
            } else {
                log.warn("返回异常:{}", EntityUtils.toString(response.getEntity()));
            }
            return result;
        }
    }



    private static String buildUrl(String host, String path, Map<String, String> querys) throws UnsupportedEncodingException {
        StringBuilder sbUrl = new StringBuilder();
        sbUrl.append(host);
        if (!StringUtils.isBlank(path)) {
            sbUrl.append(path);
        }
        if (null != querys) {
            StringBuilder sbQuery = new StringBuilder();
            for (Map.Entry<String, String> query : querys.entrySet()) {
                if (0 < sbQuery.length()) {
                    sbQuery.append("&");
                }
                if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) {
                    sbQuery.append(query.getValue());
                }
                if (!StringUtils.isBlank(query.getKey())) {
                    sbQuery.append(query.getKey());
                    if (!StringUtils.isBlank(query.getValue())) {
                        sbQuery.append("=");
                        sbQuery.append(URLEncoder.encode(query.getValue(), "utf-8"));
                    }
                }
            }
            if (0 < sbQuery.length()) {
                sbUrl.append("?").append(sbQuery);
            }
        }

        return sbUrl.toString();
    }



}